<!doctype html>
<html>
<head>
	<meta charset="UTF-8">
	<meta name="Keywords" content="">
	<meta name="Description" content="">
	<title>0619-JS练习-拼图游戏-螺旋</title>
	<style type="text/css">
		html,body,.cover{
			width: 100%;
			height: 100%;
		}
		body{
			margin: 0;
			background-color: #666;
		}
		ul{
			margin: 0;
			list-style: none;
		}
		ul,li{
			padding: 0;
		}
		p,h3{
			margin: 0;
		}
		.wrap{
			position: absolute;
			top: 0;
			bottom: 0;
			left: 0;
			right: 0;
			margin: auto;
			background-color: #333;
		}
		.jigsaw{
			position: relative;
		}
		.pic,.jigsaw i{
			/*background-image: url("images/2.jpg");*/
			background-repeat: no-repeat;
		}
		.pic p{
			display: none;
			width: 170px;
			padding: 5px;
			background-color: rgba(0,0,0,.5);
			border-radius: 0 0 5px 0;
			font-size: 12px;
			color: #fff;
			text-align: center;
		}
		.jigsaw i{
			position: absolute;
			cursor: pointer;
			transition: left .5s,top .5s;
		}
		.jigsaw i:hover{
			box-shadow: 0 0 20px 0 #f60 inset;
		}
		.cover{
			display: block;
			position: absolute;
			top: 0;
			left: 0;
			background-color: rgba(0,0,0,.5);
		}
		.cover h3{
			font-size: 30px;
			color: #fff;
			line-height: 60px;
			font-weight: 700;
			text-align: center;
		}
		.cover .ccpic{
			width: 90%;
			margin: 0 auto;
			font-size: 0;
			text-align: center;
		}
		.cover .ccpic li{
			display: inline-block;
			width: 45%;
			border: 2px solid #fff;
			cursor: pointer;
		}
		.cover .ccpic li:nth-child(1),
		.cover .ccpic li:nth-child(3){
			margin-right: 6%;
		}
		.cover .ccpic li:nth-child(1),
		.cover .ccpic li:nth-child(2){
			margin-bottom: 6%;
		}
		.cover .ccpic li img{
			width: 100%;
		}
		.cover .ctext{
			width: 100%;
			height: 150px;
			margin: 80px auto 0;
			font-weight: 700;
			color: #fff;
			text-align: center;
		}
		.cover .ctext p{
			font-size: 26px;
			line-height: 50px;
		}
		.cover .ctext span{
			color: #ff0;
		}
		.cover .ctext i{
			display: block;
			width: 100px;
			height: 30px;
			margin: 10px auto 0;
			background-color: #f60;
			font-size: 16px;
			line-height: 30px;
			font-style: normal;
			border-radius: 5px;
			cursor: pointer;
		}
		.cover .ctext i:hover{
			background-color: #ff8200;
		}
	</style>
</head>
<body>
	<div class="wrap">
		<div class="pic"><p>拼图玩法：鼠标点击 交换图片</p></div>
		<div class="jigsaw"></div>
		<div class="cover">
			<h3>拼图游戏</h3>
			<ul class="ccpic">
				<li><img src="images/1.jpg" alt=""></li>
				<li><img src="images/2.jpg" alt=""></li>
				<li><img src="images/3.jpg" alt=""></li>
				<li><img src="images/4.jpg" alt=""></li>
			</ul>
			<div class="ctext">
				<p>请从上面选择一张图片</p>
				<p></p>
				<i>开始游戏</i>
			</div>
		</div>
	</div>
</body>
<script>
	var oWarp = document.getElementsByClassName('wrap')[0],
        oCover = document.getElementsByClassName('cover')[0],
		oCcpic = oCover.getElementsByClassName('ccpic')[0],
        oCcpLi = oCcpic.getElementsByTagName('li'),
        nCcpLi = oCcpLi.length,
        oCtext = oCover.getElementsByClassName('ctext')[0],
        oCp = oCtext.getElementsByTagName('p'),
        oCbtn = oCtext.getElementsByTagName('i')[0],
        oPic = document.getElementsByClassName('pic')[0],
		oPicP = oPic.getElementsByTagName('p')[0],
		oJig = document.getElementsByClassName('jigsaw')[0],
        oJigI = oJig.getElementsByTagName('i'),
		oPwid = 600,//设置宽度 改变图片尺寸
		oPhgt = oPwid*450/800,
		oWH = {wid:oPwid,hgt:oPhgt},
        oRC = {row:3,col:4},//拼图数量可变
        nPic = oRC.row*oRC.col,//拼图数量
        oPwh = {wid:oWH.wid/oRC.col,hgt:oWH.hgt/oRC.row},//每块拼图的宽高
        aPics = [],aPicsO = [],oPick = {},oI,
		pNum = 0,n = 0,step = 0,oSw1 = true;
	
    //生成各个标签的宽高等属性
    oWarp.style.width = oWH.wid+'px';
    oWarp.style.height = oWH.hgt*2+'px';
    oPic.style.width = oWH.wid+'px';
    oPic.style.height = oWH.hgt+'px';
    oPic.style.backgroundSize = `${oWH.wid}px ${oWH.hgt}px`;
    oJig.style.width = oWH.wid+'px';
    oJig.style.height = oWH.hgt+'px';
    
    //选择图片
	for(var i=0;i<nCcpLi;i++){
		(function(i){
            oCcpLi[i].onclick = function(){
                fnClear();
                oCcpLi[i].style.border = '2px solid #ff0';
                pNum = i+1;
                oCp[0].innerHTML = `已选择图片${pNum}`;
            }
		})(i)
	}
	function fnClear(){
	    for(var i=0;i<nCcpLi;i++){
	        oCcpLi[i].style.border = '2px solid #fff';
	    }
    }

    //生成li 设置每个li的宽高 背景图片的大小和位置
	function fnCi(){
        oPic.style.backgroundImage = `url('images/${pNum}.jpg')`;
        oJig.innerHTML = '';
	    for(var j=0;j<oRC.row;j++){
	        for(var k=0;k<oRC.col;k++){
	            oI = document.createElement("i");
	            oI.style.width = oPwh.wid+'px';
	            oI.style.height = oPwh.hgt+'px';
                oI.style.backgroundImage = `url('images/${pNum}.jpg')`;
	            oI.style.backgroundPosition = `${-k*oPwh.wid}px ${-j*oPwh.hgt}px`;
	            oI.style.backgroundSize = `${oWH.wid}px ${oWH.hgt}px`;
	            oI.style.left = k*oPwh.wid+'px';
	            oI.style.top = j*oPwh.hgt+'px';
	            oJig.appendChild(oI);
	        }
	    }
    }
    
    //生成随机拼图
    // fnRdm();
	function fnRdm(){
        aPics = [];
        aPicsO = [];
        //将每个li进行随机编号 然后将其定位数值与编号一一对应 装进数组
        for(var i=0;i<nPic;i++){
            aPics.push({
                num:i,
                num2:parseInt(Math.random()*nPic*10),
                posl:oJigI[i].style.left,
                post:oJigI[i].style.top
            });
            aPicsO.push({
                num:i,
                posl:oJigI[i].style.left,
                post:oJigI[i].style.top
            })
        }
        setTimeout(fnRdmO,100);
    }
    
    //将原aPics的元素按照num2数值从小到大排序 生成随机拼图
    function fnRdmO(){
        aPics = aPics.sort(function(a,b){
            return a.num2-b.num2;
        });
        for(var i=0;i<nPic;i++){
            oJigI[i].style.left = aPics[i].posl;
            oJigI[i].style.top = aPics[i].post;
        }
	    
    }

    //点击选中拼图 再次点击交换拼图位置
	function fnMove(){
	    for(var j=0;j<nPic;j++){
	        (function(j){
	            oJigI[j].onclick = function(){
	                if(oSw1) {
	                    oJigI[j].style.boxShadow = '0 0 20px 0 #ff0 inset';
	                    oPick.j = j;
	                    oPick.left = oJigI[j].style.left;
	                    oPick.top = oJigI[j].style.top;
	                    oSw1 = false;
	                }else{
	                    oJigI[oPick.j].style.boxShadow = '';
	                    oJigI[oPick.j].style.left = oJigI[j].style.left;
	                    oJigI[oPick.j].style.top = oJigI[j].style.top;
	                    oJigI[j].style.left = oPick.left;
	                    oJigI[j].style.top = oPick.top;
	                    step++;
	                    oSw1 = true;
	                }
	                setTimeout(fnCheck,1000)
		        }
	        })(j);
	    }
    }

    //检查拼图是否完成
	function fnCheck(){
            n = 0;
            for (var k = 0; k < nPic; k++) {
                if (aPicsO[k].posl === oJigI[k].style.left && aPicsO[k].post === oJigI[k].style.top) {
                    n++;
                }
            }
            if (n === nPic) {
                oPicP.style.display = 'none';
                oCover.style.display = 'block';
                oCp[0].innerHTML = `完成了！`;
                oCp[1].innerHTML = `本次移动了<span>${step}</span>步`;
            }
    }

    //点击按钮 生成拼图
    oCbtn.onclick = function(){
	    if(pNum === 0){
            oCp[0].innerHTML = `请选择一张图片`;
	    }else{
            oPicP.style.display = 'block';
            oCover.style.display = 'none';
            step = 0;
            fnCi();
            fnRdm();
            fnMove()
	    }
    }
    
</script>
</html>